package cur.nature.component.nacos.handler;

import cur.nature.component.nacos.property.MicroPropertyBean;
import cur.nature.component.nacos.property.MicroPropertyConfig;
import cur.nature.component.nacos.util.NacosContextUtil;
import cur.nature.framework.core.log.LOG;
import cur.nature.framework.core.thread.MyThreadLocal;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeFunction;
import reactor.core.publisher.Mono;

import java.util.Optional;

public class CustomExchangeFilterFunction implements ExchangeFilterFunction {
    @Override
    public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
        // 找出 serverName, uri
        final String serviceName = request.url().getHost();
        // 根据 serviceName 找出配置信息
        final MicroPropertyConfig config = NacosContextUtil.getBean(MicroPropertyConfig.class);
        final MicroPropertyBean property = config.getProperty(serviceName);
        // 组装 url
        LOG.info("before request: " + request.url());
        final String traceId = String.valueOf(Optional.ofNullable(MyThreadLocal.getCurrentThread().get(MyThreadLocal.TRACE_ID)).orElse(""));
        final String userId = String.valueOf(Optional.ofNullable(MyThreadLocal.getCurrentThread().get(MyThreadLocal.USER_ID)).orElse(""));

        ClientRequest modifyRequest = ClientRequest.from(request)
                .header(property.getAuthKey(),property.getAuthSecret())
                .header(MyThreadLocal.TRACE_ID,traceId)
                .header(MyThreadLocal.USER_ID,userId)
                .build();
        return next.exchange(modifyRequest).doOnNext(clientResponse -> {
            MyThreadLocal.getCurrentThread().put(MyThreadLocal.TRACE_ID,traceId);
            MyThreadLocal.getCurrentThread().put(MyThreadLocal.USER_ID, userId);
            LOG.info("after request");
            MyThreadLocal.getCurrentThread().remove(MyThreadLocal.TRACE_ID);
            MyThreadLocal.getCurrentThread().remove(MyThreadLocal.USER_ID);
        });
    }
}
